package com.cpe.web.controller.student;

import static com.sql.data.response.CommonRespCode.*;
import static com.sql.data.domain.user.UserRespCode.*;
import static org.springframework.web.bind.annotation.RequestMethod.*;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

import org.javatuples.Pair;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.cpe.data.domain.member.Member;
import com.cpe.data.domain.student.physique.StudentHistoryPhysique;
import com.cpe.data.domain.student.physique.StudentPhysique;
import com.cpe.data.domain.student.physique.StudentPhysiqueForm;
import com.cpe.data.domain.student.physique.StudentPhysiqueInfo;
import com.cpe.repository.mapper.member.MemberMapper;
import com.cpe.repository.mapper.student.StudentPhysiqueMapper;
import com.cpe.transfer.student.StudentPhysiqueTransfer;
import com.cpe.web.controller.AbstractController;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.sql.data.response.JsonResponse;

import lombok.extern.slf4j.Slf4j;

/**
 * 学生体质成绩
 */
@Slf4j
@RestController
@RequestMapping("/student_physiques")
@Transactional
public class StudentPhysiqueController extends AbstractController {

	@Resource
	private StudentPhysiqueMapper studentPhysiqueMapper;

	@Resource
	private StudentPhysiqueTransfer studentPhysiqueTransfer;

	@Resource
	private MemberMapper memberMapper;

	/**
	 * 录入学生体质成绩
	 */
	@RequestMapping(method = POST)
	public JsonResponse add(@RequestBody StudentPhysiqueForm form, HttpSession session, @RequestHeader String openid,
			ModelMap modelMap) {
		Member member = (Member) session.getAttribute("loginer");
		if (member == null) {
			// 尝试从Header里读取openid
			member = memberMapper.findByOpenid(openid);
			if (member == null) {
				return JsonResponse.custom(INVALID_TOKEN);
			}
			modelMap.addAttribute("loginer", member);
		}

		if (form.stopCreate()) {
			return JsonResponse.custom(INVALID_REQUEST);
		}

		try {
			Pair<StudentPhysique, StudentPhysique> studentPhysiques = studentPhysiqueTransfer.toEntities(form);
			StudentPhysique studentPhysique = studentPhysiques.getValue0();
			if (studentPhysiqueMapper.findOne(studentPhysique) != null) {
				return JsonResponse.custom(RESOURCE_EXIST);
			}
			studentPhysique.setCreator(member.getName());
			studentPhysiqueMapper.insert(studentPhysique);

			StudentPhysique studentShape = studentPhysiques.getValue1();
			if (studentShape != null) {
				studentShape.setCreator(member.getName());
				if (studentPhysiqueMapper.findOne(studentShape) == null) {
					studentPhysiqueMapper.insert(studentShape);
				}
			}

			return JsonResponse.ok(studentPhysique);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return JsonResponse.custom(EXCEPTION);
		}
	}

	@RequestMapping(value = "/{id}", method = PUT)
	public JsonResponse update(@RequestBody StudentPhysiqueForm form, HttpSession session, @PathVariable String id,
			@RequestHeader String openid, ModelMap modelMap) {
		Member member = (Member) session.getAttribute("loginer");
		if (member == null) {
			// 尝试从Header里读取openid
			member = memberMapper.findByOpenid(openid);
			if (member == null) {
				return JsonResponse.custom(INVALID_TOKEN);
			}
			modelMap.addAttribute("loginer", member);
		}
		if (form.stopUpdate()) {
			return JsonResponse.custom(INVALID_REQUEST);
		}
		StudentPhysique studentPhysique = studentPhysiqueMapper.findById(id);
		if (studentPhysique == null) {
			return JsonResponse.custom(RESOURCE_EXIST);
		}

		try {
			Map<String, Object> update = Maps.newHashMap();
			if (form.getScore() != null && form.getScore() != studentPhysique.getScore()) {
				studentPhysique.setScore(form.getScore());
				update.put("score", form.getScore());
				// 重新计算分值
				Integer value = studentPhysiqueTransfer.calcValue(studentPhysique.getPhysiqueName(),
						studentPhysique.getScore(), studentPhysique.getStudentId());
				studentPhysique.setValue(value);
			}

			if (update.size() > 0) {
				studentPhysiqueMapper.updateById(studentPhysique);
			}

			// 重新计算体型项的分值
			StudentPhysique query = new StudentPhysique();
			BeanUtils.copyProperties(studentPhysique, query);
			query.setPhysiqueName("体型");
			StudentPhysique studentShape = studentPhysiqueMapper.findOne(query);
			if (studentShape == null) {
				// 新增体型记录
				studentShape = studentPhysiqueTransfer.generateStudentSahpe(studentPhysique);
				if (studentShape != null) {
					studentShape.setCreator(member.getName());
					Assert.hasText(studentShape.getStudentId());
					Assert.hasText(studentShape.getPhysiqueName());
					Assert.notNull(studentShape.getScore());
					Assert.notNull(studentShape.getScoreDate());
					Assert.notNull(studentShape.getValue());
					studentPhysiqueMapper.insert(studentShape);
				}
			} else {
				if ("身高".equals(studentPhysique.getPhysiqueName())) {
					query.setPhysiqueName("体重");
					StudentPhysique studentWeight = studentPhysiqueMapper.findOne(query);
					Float height = studentPhysique.getScore();
					Float weight = studentWeight.getScore();
					Pair<Integer, Integer> pair = studentPhysiqueTransfer.calcShapeValue(height, weight,
							studentPhysique.getStudentId());
					studentShape.setValue(pair.getValue0());
					studentShape.setLowOrHigh(pair.getValue1());
					studentPhysiqueMapper.updateById(studentShape);
				} else if ("体重".equals(studentPhysique.getPhysiqueName())) {
					query.setPhysiqueName("身高");
					StudentPhysique studentHeight = studentPhysiqueMapper.findOne(query);
					Float height = studentHeight.getScore();
					Float weight = studentPhysique.getScore();
					Pair<Integer, Integer> pair = studentPhysiqueTransfer.calcShapeValue(height, weight,
							studentPhysique.getStudentId());
					studentShape.setValue(pair.getValue0());
					studentShape.setLowOrHigh(pair.getValue1());
					studentPhysiqueMapper.updateById(studentShape);
				}
			}
			return JsonResponse.ok(studentPhysique);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return JsonResponse.custom(EXCEPTION);
		}
	}

	/**
	 * 获取指定家长的所有孩子的体检成绩列表
	 */
	@RequestMapping(value = "/parent/{parentId}", method = GET)
	public JsonResponse getStudentPhysiqueByParent(@PathVariable String parentId) {
		List<StudentPhysiqueInfo> list = studentPhysiqueMapper.findLastInfoByParentId(parentId);
		// 根据学生ID划分list
		Map<String, List<StudentPhysiqueInfo>> map = Maps.newHashMap();
		for (StudentPhysiqueInfo info : list) {
			if (map.containsKey(info.getStudentId())) {
				map.get(info.getStudentId()).add(info);
			} else {
				map.put(info.getStudentId(), Lists.newArrayList(info));
			}
		}

		List<List<StudentPhysiqueInfo>> listGroup = Lists.newArrayList();
		for (Entry<String, List<StudentPhysiqueInfo>> entry : map.entrySet()) {
			listGroup.add(entry.getValue());
		}
		return JsonResponse.ok(listGroup);
	}

	/**
	 * 获取指定学生的历史体检成绩
	 */
	@RequestMapping(value = "/student/{studentId}", method = GET)
	public JsonResponse getStudentHistoryPhysique(@PathVariable String studentId) {
		List<StudentPhysiqueInfo> studentPhysiqueInfos = studentPhysiqueMapper.findInfoByStudentId(studentId);
		List<StudentHistoryPhysique> historyPhysiques = studentPhysiqueTransfer.toHistoryPhysique(studentPhysiqueInfos);
		return JsonResponse.ok(historyPhysiques);
	}
}
